home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / taitosj.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  7KB  |  311 lines

  1. /***************************************************************************
  2.  
  3.   machine.c
  4.  
  5.   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
  6.   I/O ports)
  7.  
  8. ***************************************************************************/
  9.  
  10. #include "driver.h"
  11. #include "cpu/m6805/m6805.h"
  12.  
  13.  
  14. #define DEBUG_MCU    1
  15.  
  16.  
  17. static unsigned char fromz80,toz80;
  18. static int zaccept,zready;
  19.  
  20. WRITE_HANDLER( taitosj_bankswitch_w );
  21.  
  22.  
  23. void taitosj_init_machine(void)
  24. {
  25.     /* set the default ROM bank (many games only have one bank and */
  26.     /* never write to the bank selector register) */
  27.     taitosj_bankswitch_w(0, 0);
  28.  
  29.  
  30.     zaccept = 1;
  31.     zready = 0;
  32.     cpu_set_irq_line(2,0,CLEAR_LINE);
  33. }
  34.  
  35.  
  36. WRITE_HANDLER( taitosj_bankswitch_w )
  37. {
  38.     unsigned char *RAM = memory_region(REGION_CPU1);
  39.  
  40.     cpu_setbank(1,&RAM[(data & 0x80) ? 0x10000 : 0x6000]);
  41. }
  42.  
  43.  
  44.  
  45. /***************************************************************************
  46.  
  47.                            PROTECTION HANDLING
  48.  
  49.  Some of the games running on this hardware are protected with a 68705 mcu.
  50.  It can either be on a daughter board containing Z80+68705+one ROM, which
  51.  replaces the Z80 on an unprotected main board; or it can be built-in on the
  52.  main board. The two are fucntionally equivalent.
  53.  
  54.  The 68705 can read commands from the Z80, send back result codes, and has
  55.  direct access to the Z80 memory space. It can also trigger IRQs on the Z80.
  56.  
  57. ***************************************************************************/
  58. READ_HANDLER( taitosj_fake_data_r )
  59. {
  60. #if DEBUG_MCU
  61. logerror("%04x: protection read\n",cpu_get_pc());
  62. #endif
  63.     return 0;
  64. }
  65.  
  66. WRITE_HANDLER( taitosj_fake_data_w )
  67. {
  68. #if DEBUG_MCU
  69. logerror("%04x: protection write %02x\n",cpu_get_pc(),data);
  70. #endif
  71. }
  72.  
  73. READ_HANDLER( taitosj_fake_status_r )
  74. {
  75. #if DEBUG_MCU
  76. logerror("%04x: protection status read\n",cpu_get_pc());
  77. #endif
  78.     return 0xff;
  79. }
  80.  
  81.  
  82. /* timer callback : */
  83. void taitosj_mcu_real_data_r(int param)
  84. {
  85.     zaccept = 1;
  86. }
  87.  
  88. READ_HANDLER( taitosj_mcu_data_r )
  89. {
  90. #if DEBUG_MCU
  91. logerror("%04x: protection read %02x\n",cpu_get_pc(),toz80);
  92. #endif
  93.     timer_set(TIME_NOW,0,taitosj_mcu_real_data_r);
  94.     return toz80;
  95. }
  96.  
  97. /* timer callback : */
  98. void taitosj_mcu_real_data_w(int data)
  99. {
  100.     zready = 1;
  101.     cpu_set_irq_line(2,0,ASSERT_LINE);
  102.     fromz80 = data;
  103. }
  104.  
  105. WRITE_HANDLER( taitosj_mcu_data_w )
  106. {
  107. #if DEBUG_MCU
  108. logerror("%04x: protection write %02x\n",cpu_get_pc(),data);
  109. #endif
  110.     timer_set(TIME_NOW,data,taitosj_mcu_real_data_w);
  111. }
  112.  
  113. READ_HANDLER( taitosj_mcu_status_r )
  114. {
  115.     /* mcu synchronization */
  116.     cpu_yielduntil_time (TIME_IN_USEC(5));
  117.  
  118.     /* bit 0 = the 68705 has read data from the Z80 */
  119.     /* bit 1 = the 68705 has written data for the Z80 */
  120.     return ~((zready << 0) | (zaccept << 1));
  121. }
  122.  
  123. static unsigned char portA_in,portA_out;
  124.  
  125. READ_HANDLER( taitosj_68705_portA_r )
  126. {
  127. #if DEBUG_MCU
  128. logerror("%04x: 68705 port A read %02x\n",cpu_get_pc(),portA_in);
  129. #endif
  130.     return portA_in;
  131. }
  132.  
  133. WRITE_HANDLER( taitosj_68705_portA_w )
  134. {
  135. #if DEBUG_MCU
  136. logerror("%04x: 68705 port A write %02x\n",cpu_get_pc(),data);
  137. #endif
  138.     portA_out = data;
  139. }
  140.  
  141.  
  142.  
  143. /*
  144.  *  Port B connections:
  145.  *
  146.  *  all bits are logical 1 when read (+5V pullup)
  147.  *
  148.  *  0   W  !68INTRQ
  149.  *  1   W  !68LRD (enables latch which holds command from the Z80)
  150.  *  2   W  !68LWR (loads the latch which holds data for the Z80, and sets a
  151.  *                 status bit so the Z80 knows there's data waiting)
  152.  *  3   W  to Z80 !BUSRQ (aka !WAIT) pin
  153.  *  4   W  !68WRITE (triggers write to main Z80 memory area and increases low
  154.  *                   8 bits of the latched address)
  155.  *  5   W  !68READ (triggers read from main Z80 memory area and increases low
  156.  *                   8 bits of the latched address)
  157.  *  6   W  !LAL (loads the latch which holds the low 8 bits of the address of
  158.  *               the main Z80 memory location to access)
  159.  *  7   W  !UAL (loads the latch which holds the high 8 bits of the address of
  160.  *               the main Z80 memory location to access)
  161.  */
  162.  
  163. READ_HANDLER( taitosj_68705_portB_r )
  164. {
  165.     return 0xff;
  166. }
  167.  
  168. static int address;
  169.  
  170. /* timer callback : 68705 is going to read data from the Z80 */
  171. void taitosj_mcu_data_real_r(int param)
  172. {
  173.     zready = 0;
  174. }
  175.  
  176. /* timer callback : 68705 is writing data for the Z80 */
  177. void taitosj_mcu_status_real_w(int data)
  178. {
  179.     toz80 = data;
  180.     zaccept = 0;
  181. }
  182.  
  183. WRITE_HANDLER( taitosj_68705_portB_w )
  184. {
  185. #if DEBUG_MCU
  186. logerror("%04x: 68705 port B write %02x\n",cpu_get_pc(),data);
  187. #endif
  188.  
  189.     if (~data & 0x01)
  190.     {
  191. #if DEBUG_MCU
  192. logerror("%04x: 68705  68INTRQ **NOT SUPPORTED**!\n",cpu_get_pc());
  193. #endif
  194.     }
  195.     if (~data & 0x02)
  196.     {
  197.         /* 68705 is going to read data from the Z80 */
  198.         timer_set(TIME_NOW,0,taitosj_mcu_data_real_r);
  199.         cpu_set_irq_line(2,0,CLEAR_LINE);
  200.         portA_in = fromz80;
  201. #if DEBUG_MCU
  202. logerror("%04x: 68705 <- Z80 %02x\n",cpu_get_pc(),portA_in);
  203. #endif
  204.     }
  205.     if (~data & 0x04)
  206.     {
  207. #if DEBUG_MCU
  208. logerror("%04x: 68705 -> Z80 %02x\n",cpu_get_pc(),portA_out);
  209. #endif
  210.         /* 68705 is writing data for the Z80 */
  211.         timer_set(TIME_NOW,portA_out,taitosj_mcu_status_real_w);
  212.     }
  213.     if (~data & 0x10)
  214.     {
  215. #if DEBUG_MCU
  216. logerror("%04x: 68705 write %02x to address %04x\n",cpu_get_pc(),portA_out,address);
  217. #endif
  218.         memorycontextswap(0);
  219.         cpu_writemem16(address, portA_out);
  220.         memorycontextswap(2);
  221.  
  222.         /* increase low 8 bits of latched address for burst writes */
  223.         address = (address & 0xff00) | ((address + 1) & 0xff);
  224.     }
  225.     if (~data & 0x20)
  226.     {
  227. #if DEBUG_MCU
  228. logerror("%04x: 68705 read %02x from address %04x\n",cpu_get_pc(),portA_in,address);
  229. #endif
  230.         memorycontextswap(0);
  231.         portA_in = cpu_readmem16(address);
  232.         memorycontextswap(2);
  233.     }
  234.     if (~data & 0x40)
  235.     {
  236. #if DEBUG_MCU
  237. logerror("%04x: 68705 address low %02x\n",cpu_get_pc(),portA_out);
  238. #endif
  239.         address = (address & 0xff00) | portA_out;
  240.     }
  241.     if (~data & 0x80)
  242.     {
  243. #if DEBUG_MCU
  244. logerror("%04x: 68705 address high %02x\n",cpu_get_pc(),portA_out);
  245. #endif
  246.         address = (address & 0x00ff) | (portA_out << 8);
  247.     }
  248. }
  249.  
  250. /*
  251.  *  Port C connections:
  252.  *
  253.  *  0   R  ZREADY (1 when the Z80 has written a command in the latch)
  254.  *  1   R  ZACCEPT (1 when the Z80 has read data from the latch)
  255.  *  2   R  from Z80 !BUSAK pin
  256.  *  3   R  68INTAK (goes 0 when the interrupt request done with 68INTRQ
  257.  *                  passes through)
  258.  */
  259.  
  260. READ_HANDLER( taitosj_68705_portC_r )
  261. {
  262.     int res;
  263.  
  264.     res = (zready << 0) | (zaccept << 1);
  265. #if DEBUG_MCU
  266. logerror("%04x: 68705 port C read %02x\n",cpu_get_pc(),res);
  267. #endif
  268.     return res;
  269. }
  270.  
  271.  
  272.  
  273. /* Alpine Ski protection crack routines */
  274.  
  275. static int protection_value;
  276.  
  277. WRITE_HANDLER( alpine_protection_w )
  278. {
  279.     switch (data)
  280.     {
  281.     case 0x05:
  282.         protection_value = 0x18;
  283.         break;
  284.     case 0x07:
  285.     case 0x0c:
  286.     case 0x0f:
  287.         protection_value = 0x00;        /* not used as far as I can tell */
  288.         break;
  289.     case 0x16:
  290.         protection_value = 0x08;
  291.         break;
  292.     case 0x1d:
  293.         protection_value = 0x18;
  294.         break;
  295.     default:
  296.         protection_value = data;        /* not used as far as I can tell */
  297.         break;
  298.     }
  299. }
  300.  
  301. WRITE_HANDLER( alpinea_bankswitch_w )
  302. {
  303.     taitosj_bankswitch_w(offset, data);
  304.     protection_value = data >> 2;
  305. }
  306.  
  307. READ_HANDLER( alpine_port_2_r )
  308. {
  309.     return input_port_2_r(offset) | protection_value;
  310. }
  311.